<!DOCTYPE html>

<html lang="en" data-content_root="../../">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>Linked content for a project &#8212; Pytch  documentation</title>
    <link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=03e43079" />
    <link rel="stylesheet" type="text/css" href="../../_static/classic.css?v=36340f97" />
    <link rel="stylesheet" type="text/css" href="../../_static/css/pytch-classic.css?v=0321735e" />
    
    <script src="../../_static/documentation_options.js?v=7f41d439"></script>
    <script src="../../_static/doctools.js?v=9bcbadda"></script>
    <script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
    
    <link rel="icon" href="../../_static/favicon.ico"/>
    <link rel="author" title="About these documents" href="../../about.html" />
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" />
    <link rel="next" title="Pytch media library (developer notes)" href="../../medialib/developer/index.html" />
    <link rel="prev" title="Fingerprints and content hashes" href="content-hashes.html" /> 
  </head><body>
<div class="NavBar">
  <a href="../../../app/"><h1>Pytch</h1></a>
  <ul>
    <a href="https://pytch.scss.tcd.ie/"><li>About Pytch</li></a>
    <a href="../../index.html"><li>Help</li></a>
    <a href="../../../app/tutorials/"><li>Tutorials</li></a>
    <a href="../../../app/my-projects/"><li>My projects</li></a>
  </ul>
</div>
<div class="warning-work-in-progress">
  <p>These help pages are incomplete — we are working on it!</p>
</div>
  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <section id="linked-content-for-a-project">
<h1>Linked content for a project<a class="headerlink" href="#linked-content-for-a-project" title="Link to this heading">¶</a></h1>
<p>For classroom use, it is helpful for students to be able to start work
on an existing <em>specimen</em> of code.  Their task might be to modify it
in some way, or answer some questions about how it works.</p>
<p>A Pytch project, as stored in the user’s project list, therefore has
<em>linked content</em>, which can be of various kinds.  There is a
<code class="docutils literal notranslate"><span class="pre">&quot;none&quot;</span></code> kind to represent the case where there is no linked
content.  Other kinds of linked content are:</p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">&quot;specimen&quot;</span></code></dt><dd><p>The project is linked to a specimen project, usually as part of a
lesson which directs the student to make some changes to the project
or investigate it in some way.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">&quot;jr-tutorial&quot;</span></code></dt><dd><p>The project is following a script-by-script tutorial.</p>
</dd>
</dl>
<p>It’s possible that “flat” tutorial content will be folded into this
model in the future.</p>
<section id="linked-specimen">
<h2>Linked specimen<a class="headerlink" href="#linked-specimen" title="Link to this heading">¶</a></h2>
<p>A project can be linked to a <em>specimen</em> project.  When such a project
is created, it is identical to the referred-to specimen.</p>
<section id="creation-of-a-specimen-linked-project">
<h3>Creation of a specimen-linked project<a class="headerlink" href="#creation-of-a-specimen-linked-project" title="Link to this heading">¶</a></h3>
<p>It must be easy for a student, in a classroom-like environment, to
create a project from a particular specimen.  However, we want to
avoid the situation where the user ends up with lots of identical
projects cluttering up their project list.  Therefore there is
slightly fiddly logic by which the app decides whether to create a new
project for the user, open an existing one, or give that choice to the
user.  This logic lives in the <code class="docutils literal notranslate"><span class="pre">ProjectFromSpecimenFlow</span></code> model
slice.</p>
<p>If the app needs the user to make a choice from different options
(e.g., create a new project vs open an existing one), this is handled
by the component <code class="docutils literal notranslate"><span class="pre">ProjectFromSpecimenFlow</span></code>.</p>
<p>The user visits a URL like</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>https://pytch.org/app/lesson/course-1/week-1
</pre></div>
</div>
<p>where the <code class="docutils literal notranslate"><span class="pre">course-1/week-1</span></code> portion is free-form.  The single-page
app has a route <code class="docutils literal notranslate"><span class="pre">lesson/*</span></code>, the handler of which makes a request for
the specimen project at, for this example, the URL</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>https://pytch.org/lesson-specimens/course-1/week-1.zip
</pre></div>
</div>
<p>The lesson content is kept outside the main app deployment to allow
independent development and updates.  For local development, yet
another local HTTP server is required.</p>
</section>
</section>
<section id="loading-of-linked-content">
<h2>Loading of linked content<a class="headerlink" href="#loading-of-linked-content" title="Link to this heading">¶</a></h2>
<p>When the user is working with a project which has non-trivial (i.e.,
not of kind <code class="docutils literal notranslate"><span class="pre">&quot;none&quot;</span></code>) linked content, an information bar appears
above the editor pane.  This shows the title of the linked specimen,
and has a drop-down for various actions relating to the specimen.  The
linked content is loaded (asynchronously) as part of fetching the
project from the IndexedDB store.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The script-by-script IDE shows a brief summary panel for
<code class="docutils literal notranslate"><span class="pre">&quot;specimen&quot;</span></code> linked content.  For linked <code class="docutils literal notranslate"><span class="pre">&quot;jr-tutorial&quot;</span></code>
content, the IDE has a <em>lesson</em> tab in the activity bar at the
left.</p>
</div>
<section id="specimen-linked-content">
<h3>Specimen linked content<a class="headerlink" href="#specimen-linked-content" title="Link to this heading">¶</a></h3>
<p>The specimen is loaded via a URL based on the content hash of the
specimen project.  This means that the server must provide the project
zip in response to a URL like</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>https://pytch.org/lesson-specimens/_by_content_hash_/a1b2⋯a8f9.zip
</pre></div>
</div>
<p>as well as via whatever path such as
<code class="docutils literal notranslate"><span class="pre">lesson-specimens/course-1/week-1.zip</span></code> the content was originally
loaded from.</p>
<p>On the server side, this is currently implemented by making the
‘files’ under <code class="docutils literal notranslate"><span class="pre">_by_content_hash_</span></code> be symbolic links to the original
files, e.g.,</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>_by_content_hash_
├── 0f33⋯bb63.zip ⇒ ../course-1/week-5.zip
├── 2065⋯4a9a.zip ⇒ ../course-1/week-2.zip
etc
</pre></div>
</div>
<p>Currently the linked content is just the project, but in future we
might combine this with metadata, such as suggested tasks or
challenges which the student can attempt based on that specimen.</p>
</section>
</section>
</section>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="Main">
        <div class="sphinxsidebarwrapper"><ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../user/index.html">Using the Pytch web app</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../vm/user/index.html">Writing Pytch programs</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../about.html">About Pytch</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../contact.html">Contact</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../developer.html">Developer documentation</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../../developer/development-setup.html">Development setup</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../developer/design-overview.html">Design overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../vm/developer/index.html">VM</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="index.html">Webapp</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="index.html#top-level-routes">Top-level routes</a></li>
<li class="toctree-l3 current"><a class="reference internal" href="index.html#individual-aspects-of-design">Individual aspects of design</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../medialib/developer/index.html">Media library</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../developer/index.html">Website</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../build-tools/index.html">Tools</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../source-build.html">Source and build information</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../releases/changelog.html">Changelog</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../legal/index.html">Legal information</a></li>
</ul>
<div class="docs-home-link"><hr>
  <ul>
    <li>
      <a href="../../index.html">Pytch help home</a>
    <li>
  </ul>
</div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
  </body>
</html>